import sounddevice as sd
import numpy as np
from tts2 import create_tts
import logging
import threading

def play_audio(buffer,stop_event):
    devices = sd.query_devices()
    default_output_device_idx = sd.default.device[1]
    print(
        f'Use default output device: {devices[default_output_device_idx]["name"]}'
    )

    def play_audio_callback(
            outdata: np.ndarray, frames: int, time, status: sd.CallbackFlags
    ):
        n = 0
        while n < frames and not buffer.empty():
            remaining = frames - n
            k = buffer.queue[0].shape[0]

            if remaining <= k:
                outdata[n:, 0] = buffer.queue[0][:remaining]
                buffer.queue[0] = buffer.queue[0][remaining:]
                n = frames
                if buffer.queue[0].shape[0] == 0:
                    buffer.get()

                break

            outdata[n: n + k, 0] = buffer.get()
            n += k

        if n < frames:
            outdata[n:, 0] = 0
    # with 确保 event.wait() 结束后 关闭流
    with sd.OutputStream(
            channels=1,
            callback=play_audio_callback,
            dtype="float32",
            samplerate=8000,
            blocksize=1024,
    ):
        stop_event.wait()
    logging.info("play_back_thread down")

def do_tts(buffer,websocket_queue,stop_event):
    tts = create_tts()
    def generated_audio_callback(samples: np.ndarray, progress: float):
        buffer.put(samples)
        if  stop_event.is_set():
            return 0
        return 1

    while not stop_event.is_set():
        text=websocket_queue.get()
        if text == '__stop':
            break
        else:
            tts.generate(text, sid=10, speed=1.0, callback=generated_audio_callback)
    logging.info("tts thread down")
def tts_process(websocket_queue, stop_event):
    import queue
    buffer = queue.Queue()
    # 从websocket_queue中取到 text 并且阻塞异步进程
    tts_thread=threading.Thread(target=do_tts,args=(buffer,websocket_queue,stop_event))
    tts_thread.start()
    # 执行播放线程
    play_back_thread = threading.Thread(target=play_audio, args=(buffer, stop_event))
    play_back_thread.start()

    tts_thread.join()
    play_back_thread.join()